Optional values (Maybe)
The type Maybe a can be used in situations where some value can
not be necessarily computed. Its values are either Nothing or
Just v where the type of v is a.
data Maybe a (Builtin)
Represents an optional value.
Nothing :: Maybe b (Builtin)
Just :: b -> Maybe b (Builtin)
fromJust :: Maybe a -> a (Prelude)
Given Just x this function returns x. If the parameter is Nothing, the function raises an exception.
fromMaybe :: a -> Maybe a -> a (Prelude)
fromMaybe def v returns def if v=Nothing and x if v=Just x.
execJust :: Maybe a -> (a -> <c> b) -> <c> () (Prelude)
execJust v f executes the function f with parameter value x, if v=Just x. If v=Nothing, the function does nothing.
filterJust :: [Maybe a] -> [a] (Prelude)
Takes those elements of the input list that match (Just x) and adds the contents to the resulting list. For example,
filterJust [Just 1, Nothing, Just 5] = [1, 5]
orElse :: Maybe a -> <b> a -> <b> a (Prelude)
Provides a default value if the first parameter is Nothing.
The default value is evaluated only if needed. The function
can be used as an operator and is right associative so that
the following is possible:
tryWithTheFirstMethod
`orElse` tryWithTheSecondMethod
`orElse` fail "Didn't succeed."
elemMaybe :: a -> Maybe a -> Boolean (Prelude)
elemMaybe v1 (Just v2) returns true if v1 == v2. elemMaybe v1 Nothing is always false.
When to use Maybe vs exceptions
Prefer Maybe when:
- Absence of a value is a normal, expected outcome (e.g. looking up a key that may not
exist, parsing user input that might be malformed).
- The caller needs to distinguish between "value found" and "value not found" without
catching an exception.
Use exceptions / runtime errors when the absence signals a programming error — for
example, fromJust Nothing throws an exception and is appropriate only when you are
certain the value is Just.
Maybe as a monad
Maybe forms a monad: a chain of operations where any step may produce Nothing, and
the entire chain short-circuits to Nothing as soon as that happens. This avoids nested
match expressions:
// Without monad:
lookupFullName db firstName =
match lookup firstName db with
Nothing -> Nothing
Just last -> match lookup last db with
Nothing -> Nothing
Just full -> Just full
// With mdo:
lookupFullName db firstName = mdo
last <- lookup firstName db
full <- lookup last db
return full
The mdo block desugars to >>= (bind) chains. If any step yields Nothing, the
remainder is skipped and the whole expression returns Nothing.
Either — errors with a reason
Either A B is a two-constructor type:
data Either a b = Left a | Right b
By convention, Left carries an error value and Right carries a success value. Use
Either when you need to return a failure reason alongside a possible result:
safeDivide :: Double -> Double -> Either String Double
safeDivide _ 0.0 = Left "division by zero"
safeDivide x y = Right (x / y)
match safeDivide 10.0 0.0 with
Left err -> print "Error: \(err)"
Right val -> print "Result: \(val)"
Either is also a monad (binding on Right, short-circuiting on Left), which makes it
suitable for chaining fallible operations in a mdo block.
|